
using System;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using Contracts.Caching;
using Contracts.ServiceContracts.Log;
using Types.Attributes;
using Types.Constants;
using Types.Enumerations;

namespace Services.BusinessObjects.Log
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [DefaultDatabase("DEFAULT_DB_NAME")]
    internal partial class ExceptionLogBS : BusinessBase, IExceptionLog
    {
        /// <summary>
        /// If possible Errors are written to database. If not, they are written to event log with id of 5555.
        /// </summary>
        /// <param name="pExceptionDetail">Error Detail</param>
        /// <param name="pMessage">Additional information message</param>
        /// <param name="pLogger">Module, page, class, method etc.</param>
        /// <param name="pMethod">The Method where error occured</param>
        public string LogException(string pExceptionDetail, string pMessage, string pLogger, string pMethod)
        {
            try
            {
                if (ContextData == null)
                {
                    string errMsg = string.Format("ERROR OCCURED WHILE GETTING ERROR INFO: IBContextData is null | ORJINAL ERROR: Message: {0} | Error Details: {1}", pMessage, pExceptionDetail);
                    EventLog.WriteEntry(CommonConstants.EventLogSource.Application, errMsg, EventLogEntryType.Error, ExceptionEventLogId.ContextNull);
                    return ExceptionPresentationId.ContextNull;
                }

                int depKey = this.ContextData.DepartmentKey;
                int personelKey = this.ContextData.PersonelKey;
                string serverInfo = this.ContextData.IssName;
                string clientInfo = this.ContextData.ClientInfo;
                string currentURL = this.ContextData.CurrenPageUrl;

                //*** If one or more of fallowing value length is greater then defined in database, it is cutting to prevent error
                if (pLogger.Length > 50) pLogger = pLogger.Substring(0, 50);
                if (clientInfo.Length > 200) clientInfo = clientInfo.Substring(0, 200);
                if (serverInfo.Length > 50) serverInfo = serverInfo.Substring(0, 50);
                if (currentURL.Length > 150) currentURL = currentURL.Substring(0, 150);
                if (pMethod.Length > 100) pMethod = pMethod.Substring(0, 97) + "...";
                if (pMessage.Length > 250) pMessage = pMessage.Substring(0, 250);

                //*** Set default values for empty parameters
                if (string.IsNullOrEmpty(pLogger)) pLogger = "Unknown";
                if (string.IsNullOrEmpty(currentURL)) currentURL = "/";
                if (string.IsNullOrEmpty(pMethod)) pMethod = "Unknown";
                if (string.IsNullOrEmpty(pMessage)) pMessage = "No Message";
                if (string.IsNullOrEmpty(pExceptionDetail)) pExceptionDetail = "No Error Detail";

                return SaveExceptionToDatabase(pExceptionDetail, pMessage, pLogger, depKey, personelKey, clientInfo, serverInfo, currentURL, pMethod);
            }
            catch (Exception exc)
            {
                string errMsg = string.Format("ERROR OCCURED WHILE GETTING ERROR INFO: {0} | ORJINAL ERROR: Message: {1} | Error Details: {2}", exc.ToString(), pMessage, pExceptionDetail);
                EventLog.WriteEntry(CommonConstants.EventLogSource.Application, errMsg, EventLogEntryType.Error, ExceptionEventLogId.UnableToRetrieveErrorInformation);
                return ExceptionPresentationId.UnableToRetrieveErrorInformation;
            }
        }

        public bool IsExceptionInUnlogList(string pExceptionMessage)
        {
            //Check if exception message is written in "EXCEPTION_UNLOG" table or not.
            //If exception message is written in this table then, don't write this exception to log.

            int unlogKey = 0;
            unlogKey = ((DataTable)CacheProvider.Provider.GetCacheItem("EXCEPTION_UNLOGDataSet").Tables[0])
                .AsEnumerable().AsQueryable()
                .Where(p =>
                    p.Field<string>("UnLogMessage").StartsWith(pExceptionMessage) &&
                                                    p.Field<string>("Active").Equals("Y"))
                .Select(a => a.Field<int>("ExceptionUnLogKey"))
                .FirstOrDefault();
            if (unlogKey > 0) return true; else return false;
        }

        private string SaveExceptionToDatabase(string pExceptionDetail, string pExceptionMessage, string pLogger, int pDepartmentKey, int pUserId, string pClientInfo, string pServerInfo, string pPageURL, string pMethod)
        {
            try
            {
                ExceptionLog prm = new ExceptionLog();
                prm.ExceptionDate = DateTime.Now;
                prm.ExceptionLogger = pLogger;
                prm.UserKey = pUserId;
                prm.UserDepartmentKey = pDepartmentKey;
                prm.ClientInformations = pClientInfo;
                prm.ServerInformations = pServerInfo;
                prm.PageURL = pPageURL;
                prm.MethodName = pMethod;
                prm.ExceptionMessage = pExceptionMessage;
                prm.ExceptionDetail = pExceptionDetail;

                int logKey = Insert(prm);
                return logKey.ToString();
            }
            catch (Exception exc)
            {
                string errMsg = string.Format("EXCEPTION OCCURED WHILE EXCEPTION HAS WRITTEN TO DATABASE: {0} | ORJINAL EXCEPTION: Mesaj: {1} | Exception Details: {2}", exc.ToString(), pExceptionMessage, pExceptionDetail);
                EventLog.WriteEntry(CommonConstants.EventLogSource.Application, errMsg, EventLogEntryType.Error, ExceptionEventLogId.UnableToWriteErrorToDatabase);
                return ExceptionPresentationId.UnableToWriteErrorToDatabase;
            }
        }
    }
}

